﻿using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using LingDong.ConfigProvider;
using NLog;

namespace LingDong.SerializeProvider
{
    public class Serializer
    {
        static Serializer()
        {
            formatter = new BinaryFormatter();
            providerIndex = ConfigCommon.Default.SerializeProviderIndex;
        }

        public static void Serialize<T>(Stream destination, T instance)
        {
            // DotNetDefault
            if (providerIndex == 0)
            {
                formatter.Serialize(destination, instance);
            }
            // ProtoBuf
            else if (providerIndex == 1)
            {
                ProtoBuf.Serializer.SerializeWithLengthPrefix<T>(destination, instance, ProtoBuf.PrefixStyle.Fixed32);
            }
            else
            {
                Logger logger = NLog.LogManager.GetCurrentClassLogger();
                logger.Error("Known format in ConfigCommon.Default.SerializeProvider: {0}", 
                    ConfigCommon.Default.SerializeProviderCandidateSet[ConfigCommon.Default.SerializeProviderIndex]);
            }
        }

        public static T Deserialize<T>(Stream source)
        {
            // DotNetDefault
            if (providerIndex == 0)
            {
                return (T)formatter.Deserialize(source);
            }
            // ProtoBuf
            else if (providerIndex == 1)
            {
                return ProtoBuf.Serializer.DeserializeWithLengthPrefix<T>(source, ProtoBuf.PrefixStyle.Fixed32);
            }
            else
            {
                Logger logger = NLog.LogManager.GetCurrentClassLogger();
                logger.Error("Known format in ConfigCommon.Default.SerializeProvider: {0}", 
                    ConfigCommon.Default.SerializeProviderCandidateSet[ConfigCommon.Default.SerializeProviderIndex]);
                return default(T);
            }
        }

        private static BinaryFormatter formatter;
        private static int providerIndex;
    }
}
